<template>
  <div class="easy-switch">
    <div
      class="easy-switch-wrapper"
      :style="{
        width: state.coreWidth + 'px',
        height: state.coreHeight + 'px',
        'border-radius': state.coreHeight / 2 + 'px',
        background: state.status ? state.switchBg : '#e9ebef',
      }"
      :class="{ 'easy-close': !state.status, 'easy-disabled': disabled }"
      @click="handleSwitchs"
    >
      <div
        v-if="inactiveText && !state.status"
        :style="{
          width: state.coreWidth - state.coreHeight + 2 + 'px',
          height: state.coreHeight - 2 + 'px',
          'line-height': state.coreHeight - 2 + 'px',
          display: 'inline-block',
          position: 'absolute',
          overflow: 'hidden',
          'text-overflow': 'ellipsis',
          'white-space': 'nowrap',
          left: '6px',
        }"
      >
        <span>{{ inactiveText }}</span>
      </div>
      <div
        class="easy-slider"
        :style="{
          width: state.coreHeight - 2 + 'px',
          height: state.coreHeight - 2 + 'px',
          left: state.left + 'px',
        }"
      ></div>
      <div
        v-if="activeText && state.status"
        :style="{
          width: state.coreWidth - state.coreHeight + 2 + 'px',
          height: state.coreHeight - 2 + 'px',
          'line-height': state.coreHeight - 2 + 'px',
          display: 'inline-block',
          position: 'absolute',
          overflow: 'hidden',
          'text-overflow': 'ellipsis',
          'white-space': 'nowrap',
          left: state.coreHeight + 'px',
        }"
      >
        <span>{{ activeText }}</span>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, watch, onMounted, reactive } from 'vue'
import { basicProps } from './props'
interface State {
  status: boolean
  switchBg: string
  coreWidth: number
  coreHeight: number
  left: number
}
export default defineComponent({
  name: 'Switch',
  props: basicProps,
  setup(props, context) {
    const { check, background, disabled, size } = props
    const state: State = reactive({
      status: true,
      switchBg: '#1890ff',
      coreWidth: 0,
      coreHeight: 0,
      left: 1,
    })
    onMounted(() => {
      if (size === 'small') {
        state.coreWidth = 60
        state.coreHeight = 30
      } else {
        state.coreWidth = 100
        state.coreHeight = 40
      }
      if (state.status !== check) {
        state.status = check
        changeStatus()
      }
      if (state.switchBg !== background) {
        state.switchBg = background
      }
    })

    const changeStatus = () => {
      if (state.status) {
        state.left = 1
      } else {
        state.left = state.coreWidth - (state.coreHeight - 1)
      }
    }
    const handleSwitchs = () => {
      if (disabled) {
        return
      }
      state.status ? (state.status = false) : (state.status = true)
      changeStatus()
      context.emit('change', state.status) //传change事件，可以让父组件使用@change
    }
    watch(
      () => [check, background, status],
      ([newcheck]: [boolean], [newbackground]: [string]) => {
        changeStatus()
        if (newcheck) {
          state.status = newcheck //拿到父组件传给子组件的值
        }
        if (newbackground) {
          if (newbackground.indexOf('#') === -1) {
            state.switchBg = '#1890ff'
          } else {
            state.switchBg = newbackground
          }
        }
      }
    )
    return {
      state,
      handleSwitchs,
      ...props,
    }
  },
})
</script>
<style lang="scss">
.easy-switch {
  display: inline-block;
  .easy-switch-wrapper {
    width: 60px;
    height: 30px;
    background: #1890ff;
    border-radius: 15px;
    position: relative;
    cursor: pointer;
    .easy-slider {
      width: 28px;
      height: 28px;
      border-radius: 50%;
      background: #ffffff;
      position: absolute;
      top: 1px;
      left: 1px;
      z-index: 3;
      transition: left 0.4s;
    }
  }

  .easy-close {
    background: #e9ebef;
  }

  .easy-disabled {
    cursor: not-allowed;
    opacity: 0.6;
  }
}
</style>
